package cn.bugstack.service.impl;

import cn.bugstack.common.constants.Constants;
import cn.bugstack.dao.IOrderDao;
import cn.bugstack.domain.po.PayOrder;
import cn.bugstack.domain.req.ShopCartReq;
import cn.bugstack.domain.res.PayOrderRes;
import cn.bugstack.domain.vo.ProductVO;
import cn.bugstack.service.IOrderService;
import cn.bugstack.service.rpc.ProductRPC;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.request.AlipayTradePagePayRequest;

import com.google.common.eventbus.EventBus;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * @Author: 小新
 * @Date: 2025/3/18 18:52
 * @Description: 订单服务实现类
 * @Version: v1.0
 */
@Service
@Slf4j
public class OrderServiceImpl implements IOrderService {


    @Value("${alipay.notify_url}")
    private String notifyUrl;

    @Value("${alipay.return_url}")
    private String returnUrl;

    @Resource
    private IOrderDao orderDao;

    @Resource
    private ProductRPC productRPC;

    @Resource
    private AlipayClient alipayClient;

    @Resource
    private EventBus eventBus;


    /**
     * 创建订单
     *
     * @param shopCartReq
     * @return
     */
    @Override
    public PayOrderRes createOrder(ShopCartReq shopCartReq) throws AlipayApiException {
        //1. 查询当前订单是否未支付，或掉单
        PayOrder payOrderRes = new PayOrder();
        payOrderRes.setUserId(shopCartReq.getUserId());
        payOrderRes.setProductId(shopCartReq.getProductId());

        PayOrder unPaidOrder = orderDao.queryUnPaidOrder(payOrderRes);

        //2.1 如果订单存在，但是未支付，则返回未支付订单
        if (null != unPaidOrder && Constants.OrderStatusEnum.PAY_WAIT.getCode().equals(unPaidOrder.getStatus())) {
            log.info("当前订单未支付，userId：{}, orderId: {}, productId: {}", shopCartReq.getUserId(), unPaidOrder.getOrderId(), shopCartReq.getProductId());
            return PayOrderRes.builder()
                    .orderId(unPaidOrder.getOrderId())
                    .payUrl(unPaidOrder.getPayUrl())
                    .build();
        }

        //2.2 如果订单存在
        if (null != unPaidOrder && Constants.OrderStatusEnum.CREATE.getCode().equals(unPaidOrder.getStatus())) {
            log.info("当前订单未支付,创建支付单开始，userId：{}, orderId: {}, productId: {}", shopCartReq.getUserId(), unPaidOrder.getOrderId(), shopCartReq.getProductId());
            PayOrder payOrder = doPrePayOrder(unPaidOrder.getOrderId(),unPaidOrder.getProductId(),unPaidOrder.getProductName(),unPaidOrder.getTotalAmount());
            return PayOrderRes.builder()
                    .orderId(payOrder.getOrderId())
                    .payUrl(payOrder.getPayUrl())
                    .build();
        }


        //3.查询商品，创建订单
        ProductVO productVO = productRPC.queryProductByProductId(shopCartReq.getProductId());
        String orderId = RandomStringUtils.randomNumeric(16);
        orderDao.insert(PayOrder.builder()
                .userId(payOrderRes.getUserId())
                .orderId(orderId)
                .orderTime(new Date())
                .productId(productVO.getProductId())
                .productName(productVO.getProductName())
                .totalAmount(productVO.getPrice())
                .status(Constants.OrderStatusEnum.CREATE.getCode())
                .build());

        PayOrder payOrder = doPrePayOrder(orderId,productVO.getProductId(),productVO.getProductName(),productVO.getPrice());
        return PayOrderRes.builder()
                .userId(payOrder.getUserId())
                .orderId(orderId)
                .payUrl(payOrder.getPayUrl())
                .build();
    }

    @Override
    public void changeOrderPyaSuccess(String orderId) {
       PayOrder payOrderReq=new PayOrder();
       payOrderReq.setOrderId(orderId);
       payOrderReq.setStatus(Constants.OrderStatusEnum.PAY_SUCCESS.getCode());
       orderDao.changeOrderPaySuccess(payOrderReq);
       eventBus.post(JSON.toJSONString(payOrderReq));
    }

    @Override
    public List<String> queryNoPayNotifyOrder() {
        return orderDao.queryNoPayNotifyOrder();
    }

    @Override
    public List<String> queryTimeoutClosedOrderList() {
        return orderDao.queryTimeoutCloseOrderList();
    }

    @Override
    public boolean changeOrderClose(String orderId) {
        return orderDao.changeOrderClose(orderId);
    }


    /**
     * 创建待支付订单
     * @param orderId
     * @param productId
     * @param productName
     * @param totalAmount
     * @return
     * @throws AlipayApiException
     */
    private PayOrder doPrePayOrder(String orderId, String productId, String productName,BigDecimal totalAmount) throws AlipayApiException {
        AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
        request.setNotifyUrl(notifyUrl);
        request.setReturnUrl(returnUrl);

        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", orderId);
        bizContent.put("total_amount", totalAmount.toString());
        bizContent.put("subject", productName);
        bizContent.put("product_code", "FAST_INSTANT_TRADE_PAY");
        request.setBizContent(bizContent.toString());

        String form = alipayClient.pageExecute(request).getBody();

        PayOrder payOrder = new PayOrder();
        payOrder.setOrderId(orderId);
        payOrder.setPayUrl(form);
        payOrder.setStatus(Constants.OrderStatusEnum.PAY_WAIT.getCode());

        //更新订单状态为待支付
        orderDao.updateOrderPayInfo(payOrder);

        return payOrder;

    }
}
